package com.binarycube.webserver.datasource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONObject;

/**
 * An abstraction of a data record, that can either be a set of mapped data (String->Object)
 * or a list/array of data values.
 * 
 * @author chris
 *
 */
public class Record {

	public enum Type {
		MAPPED, INDEXED, JSON;
	}
	
	
	Map<String, Object> _MappedFields;
	List<Object> _IndexedFields;
	JSONObject _JSONObject;
	Type _type;
	
	
	public static Record MappedRecord(){
		return new Record(Type.MAPPED);
	}
	
	public static Record JSONRecord(){
		return new Record(Type.JSON);
	}
	
	public static Record IndexedRecord(){
		return new Record(Type.INDEXED);
	}
	
	private Record(Type type){
		_type = type;
		if (type == Type.MAPPED) _MappedFields = new HashMap<String,Object>();
		else  _IndexedFields = new ArrayList<Object>();
	}
	
	public Object get(String key) {
		if (_type == Type.MAPPED) return _MappedFields.get(key);
		else if (_type == Type.JSON) return _JSONObject.get(key);
		else return null;
	}
	
	public Object get(int i) {
		if (_type == Type.INDEXED) return _IndexedFields.get(i);
		return null;
		
	}
	
	@SuppressWarnings("unchecked")
	public Set<String> getKeys(){
		if (_type == Type.MAPPED) return _MappedFields.keySet();
		else if (_type == Type.JSON) return _JSONObject.keySet();
		else return null;
	}
	
	public void put(String key, Object value) {
		_MappedFields.put(key, value);
	}
	
	public void add(Object value) {
		_IndexedFields.add(value);
	}
	
	public void set(int index, Object value){
		_IndexedFields.set(index, value);
	}
	
	public void set(Object[] fieldData) {
		for (Object field : fieldData) {
			_IndexedFields.add(field);
		}
	}
	
	public Collection<Object> getValues(){
		if (_type == Type.INDEXED) return _IndexedFields;
		else if (_type == Type.MAPPED) return _MappedFields.values();
		else return null;
	}
	
	public void set(JSONObject json) {
		_JSONObject = json;
	}
	
	public int size(){
		if (_type == Type.INDEXED) return _IndexedFields.size();
		else if (_type == Type.MAPPED) return _MappedFields.size();
		else if (_type == Type.JSON) return _JSONObject.size();
		else return 0;
	}
	
	public String toString(){
		if (_type == Type.INDEXED) {
			return _IndexedFields.toString();
		} else if (_type == Type.MAPPED) {
			return _MappedFields.toString();
		} else if (_type == Type.JSON) {
			return _JSONObject.toString();
		} else return "";
	}
	
}
